#define N 8
const unsigned char code_a[N] = {1,1,1,1,1,1,1,1};
const unsigned char code_b[N] = {1,0,1,0,1,0,1,0};

int multiplex_cdm(unsigned char *c, const int c_size, const unsigned char *a, const int a_len, const unsigned char *b, const int b_len) {
    int max_len = a_len > b_len ? a_len : b_len;
    if (c_size < 8 + N * max_len) return -1;
    for (int i = 0; i < 4; i++) c[i] = (a_len >> (8 * i)) & 0xFF;
    for (int i = 0; i < 4; i++) c[4 + i] = (b_len >> (8 * i)) & 0xFF;
    int j = 8;
    for (int i = 0; i < max_len; i++) {
        for (int k = 0; k < N; k++) {
            c[j + i * N + k] = 0;
        }
    }
    for (int i = 0; i < a_len; i++) {
        for (int k = 0; k < N; k++) {
            if (a[i]) c[8 + i * N + k] += code_a[k];
        }
    }
    for (int i = 0; i < b_len; i++) {
        for (int k = 0; k < N; k++) {
            if (b[i]) c[8 + i * N + k] += code_b[k];
        }
    }
    return 0;
}

int demultiplex_cdm(unsigned char *a, const int a_size, unsigned char *b, const int b_size, const unsigned char *c, const int c_len) {
    int a_len = 0, b_len = 0;
    for (int i = 0; i < 4; i++) a_len |= (c[i] << (8 * i));
    for (int i = 0; i < 4; i++) b_len |= (c[4 + i] << (8 * i));
    int actual_a_len = a_len < a_size ? a_len : a_size;
    int actual_b_len = b_len < b_size ? b_len : b_size;
    for (int i = 0; i < actual_a_len; i++) {
        int sum = 0;
        for (int k = 0; k < N; k++) {
            sum += c[8 + i * N + k] * code_a[k];
        }
        a[i] = (sum > N/2) ? 1 : 0;
    }
    for (int i = 0; i < actual_b_len; i++) {
        int sum = 0;
        for (int k = 0; k < N; k++) {
            sum += c[8 + i * N + k] * code_b[k];
        }
        b[i] = (sum > N/2) ? 1 : 0;
    }
    return 0;
}